#pragma once

#include <afxtempl.h>
#include "YJCtrl/YJListCtrl.h"
#include "DirectoryMonitor/DirectoryChanges.h"
#include "YJDriveBar.h"

class CYJFileListCtrl;
class CDirectoryChangeHandler_FileList;

class CDirectoryChangeHandler_FileList : public CDirectoryChangeHandler
{
public:
	CDirectoryChangeHandler_FileList(CYJFileListCtrl & file_list)
		: CDirectoryChangeHandler(),
		m_fileList( file_list ){}
protected:
	CYJFileListCtrl & m_fileList;

	//These functions are called when the directory to watch has had a change made to it
	void On_FileAdded(const CString & strFileName);
	void On_FileRemoved(const CString & strFileName);
	void On_FileModified(const CString & strFileName);
	void On_FileNameChanged(const CString & strOldFileName, const CString & strNewFileName);
	void On_WatchStarted(DWORD dwError, const CString & strDirectoryName);
	void On_WatchStopped(const CString & strDirectoryName);
};

// CYJFileListCtrl

typedef struct tagExtInfo
{
	tagExtInfo(CString csType = _T(""), int nImageIndex = 0):
		m_csType(csType),
		m_nImageIndex(nImageIndex)
		{};
	CString m_csType;
	int		m_nImageIndex;
}EXT_INFO;

typedef CMap<CString,LPCTSTR,EXT_INFO,EXT_INFO&> CExtInfoMap;

class CYJFileListCtrl : public CYJListCtrl
{
	DECLARE_DYNAMIC(CYJFileListCtrl)

private:
	const static CString	m_arrSizeUnit[5];
	
	CString			m_csCurrentPath;
	CString			m_csParentPath;
	CString			m_csFileFilter;
	int				m_nUpIconIndex;
	CMenu			m_popupMenu;
	CWnd*			m_pWndMenuNotify;
	CPoint			m_ptRClick;
	BOOL			m_bFocus;

	CDirectoryChangeHandler_FileList	m_dirChangeHandler;
	CDirectoryChangeWatcher				m_dirChangeWatcher;

	CString GenerateFileSize(DOUBLE lFileSize, int nUnit);
	HIMAGELIST GetSystemImageList(BOOL bLarge);
	CString GetFileExt(CString csFilePath, CString csFileName, BOOL isFolder = FALSE);
	void GetExtInfo(CString csFilePath, CString csFileExt, EXT_INFO& extInfo);

protected:
	DECLARE_MESSAGE_MAP()

public:

/*
#pragma pack(1)
	typedef struct tagFileListData
	{
		tagFileListData(bool bIsFolder = false, LONGLONG llSize = 0):
			m_bIsFolder(bIsFolder),
			m_llSize(llSize)
			{}
		bool m_bIsFolder;
		LONGLONG m_llSize;
	}FILE_LIST_DATA;
#pragma pack()*/

	static CExtInfoMap		m_mapExtInfo;

	static BOOL FileExist(CString csFilePath);
	static BOOL IsDirectory(CString csFilePath);
	static BOOL IsHidden(CString csFilePath);
	static CString ExpandShortcut(const CString& inFile);

	CYJFileListCtrl();
	virtual ~CYJFileListCtrl();

	void SetFileFilter(CString csFilter = _T("*.*"));
	void LoadFileList(CString csPath = _T("C:\\"));
	void SetSort(int nColumn = 0, bool bAscending = true);
	bool SortColumn(int columnIndex, bool ascending);
	CString GetCurrentPath() {return m_csCurrentPath; }
	void AddFile(const CString& csFileName, BOOL bIsFolder = FALSE);
	void Rename(const CString& csOldName, const CString& csNewName);
	void DeleteFile(const CString& csFileName);
	int FindFile(const CString& csFileName);
	void UpdateFile(const CString& csFileName);
	BOOL SetPopupMenu(UINT nIDResource, CWnd* pWndMenuNotify);
	void ShowContextMenu(CPoint point);
	void ShowContextMenu();
	BOOL IsFocus();
	void Refresh();
	void ShowProperties();


	afx_msg void OnNMDblclk(NMHDR *pNMHDR, LRESULT *pResult);
	afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
	afx_msg void OnNMRclick(NMHDR *pNMHDR, LRESULT *pResult);
	afx_msg void OnDestroy();
	afx_msg void OnLvnBeginlabeledit(NMHDR *pNMHDR, LRESULT *pResult);
	afx_msg void OnLvnEndlabeledit(NMHDR *pNMHDR, LRESULT *pResult);
	afx_msg LRESULT OnDriveButtonClicked(WPARAM wParam, LPARAM lParam);

	virtual BOOL PreTranslateMessage(MSG* pMsg);
	afx_msg void OnSetFocus(CWnd* pOldWnd);
	afx_msg void OnKillFocus(CWnd* pNewWnd);
};


